package com.gitee.wsl.mathematics.matrix.mat3.ext

import com.gitee.wsl.mathematics.matrix.mat3.Matrix3
import com.gitee.wsl.mathematics.matrix.mat4.Matrix4
import com.gitee.wsl.mathematics.vector.vec2.MutableVector2
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import com.gitee.wsl.mathematics.vector.vec3.MutableVector3
import com.gitee.wsl.mathematics.vector.vec3.Vector3


fun <T:Number> Matrix3<T,*,*>.transform(vec: MutableVector3<T, *>) {
    vec.x = vec.x * this[0, 0] + vec.y * this[0, 1] + vec.z * this[0, 2]
    vec.y = vec.x * this[1, 0] + vec.y * this[1, 1] + vec.z * this[1, 2]
    vec.z = vec.x * this[2, 0] + vec.y * this[2, 1] + vec.z * this[2, 2]
}

fun <T:Number,V: Vector3<T, V>> MutableVector3<T, V>.transform(mat3: Matrix3<T, *, *>) = mat3.transform(this)


fun <T:Number,V: Vector3<T, V>> Vector3<T, V>.transform(mat4: Matrix4<T, *, *>):V{
    val vecx = x * mat4[0, 0] + y * mat4[0, 1] + z * mat4[0, 2]
    val vecy = x * mat4[1, 0] + y * mat4[1, 1] + z * mat4[1, 2]
    val vecz = x * mat4[2, 0] + y * mat4[2, 1] + z * mat4[2, 2]
    return create(vecx,vecy,vecz)
}

fun <T:Number,V: Vector3<T, V>> MutableVector3<T, V>.transform(mat4: Matrix4<T, *, *>) {
    val vecx = x * mat4[0, 0] + y * mat4[0, 1] + z * mat4[0, 2]
    val vecy = x * mat4[1, 0] + y * mat4[1, 1] + z * mat4[1, 2]
    val vecz = x * mat4[2, 0] + y * mat4[2, 1] + z * mat4[2, 2]
    set(vecx,vecy,vecz)
}

fun <T:Number,V: Vector3<T, V>> Matrix4<T, *, *>.transform(vector3: MutableVector3<T, V>) = vector3.transform(this)


fun <T:Number> Matrix3<T,*,*>.transform(vec: MutableVector2<T, *>) {
    vec.x = vec.x * this[0, 0] + vec.y * this[0, 1] + this[0, 2]
    vec.y = vec.x * this[1, 0] + vec.y * this[1, 1] + this[1, 2]
}

fun <T:Number,V: Vector2<T, V>> MutableVector2<T, V>.transform(mat3: Matrix3<T, *, *>) = mat3.transform(this)


fun <T:Number,V:Vector2<T, V>> Vector2<T, V>.transform(mat3: Matrix3<*,*,*>):V {
    val retx = x * mat3[0, 0] + y * mat3[0, 1] + mat3[0, 2]
    val rety = x * mat3[1, 0] + y * mat3[1, 1] + mat3[1, 2]
    return create(retx,rety)
}

